package cn.shengongying.api.controller;

import cn.shengongying.anon.User;
import cn.shengongying.api.dto.IdInDTO;
import cn.shengongying.api.dto.OrderInDTO;
import cn.shengongying.api.dto.PageInDTO;
import cn.shengongying.api.vo.OrderListVo;
import cn.shengongying.bean.BaseUser;
import cn.shengongying.bean.ResponseResult;
import cn.shengongying.enums.CacheKeyEnum;
import cn.shengongying.enums.ResponseCodeEnum;
import cn.shengongying.model.BossOrder;
import cn.shengongying.model.BossPosition;
import cn.shengongying.model.PayResult;
import cn.shengongying.model.UserDiscountInfo;
import cn.shengongying.service.IBossOrderService;
import cn.shengongying.service.IBossPositionService;
import cn.shengongying.service.IUserDiscountInfoService;
import cn.shengongying.service.PayFactory;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author : RXK
 * Date : 2021-7-24 18:02
 * Code Less Think More
 * Desc:
 */
@RestController
@Api(tags = "支付记录")
@RequestMapping("/boss/order")
public class OrderController extends BaseController {

    private final PayFactory payFactory;

    private final IBossOrderService orderService;

    private final IBossPositionService bossPositionService;

    private final RedisTemplate<String, String> redisTemplate;

    private final IUserDiscountInfoService userDiscountInfoService;


    public OrderController(PayFactory payFactory, IBossOrderService orderService, IBossPositionService bossPositionService, RedisTemplate<String, String> redisTemplate, IUserDiscountInfoService userDiscountInfoService) {
        this.payFactory = payFactory;
        this.orderService = orderService;
        this.bossPositionService = bossPositionService;
        this.redisTemplate = redisTemplate;
        this.userDiscountInfoService = userDiscountInfoService;
    }


    @PostMapping("/list")
    @ApiOperation(value = "支付记录列表")
    public ResponseResult<List<OrderListVo>> list(@ApiIgnore @User BaseUser baseUser, @RequestBody PageInDTO inDTO) {
        List<BossOrder> orderList = orderService.pageList(baseUser.getId(), inDTO.offset(), inDTO.getPageSize());
        List<Long> positionIds = orderList.stream()
                .map(BossOrder::getExtId)
                .collect(Collectors.toList());
        List<BossPosition> positionList = null;
        if (CollectionUtils.isNotEmpty(positionIds)) {
            positionList = bossPositionService.listByIds(positionIds);
        }
        List<OrderListVo> voList = OrderListVo.list(orderList, positionList);
        return ResponseResult.success(voList);
    }

    @ApiOperation(value = "下单", notes = "id为职位id")
    @PostMapping("/create")
    public ResponseResult<PayResult> create(@ApiIgnore @User BaseUser baseUser, @RequestBody @Validated OrderInDTO inDTO) {
        BossPosition position = bossPositionService.getById(inDTO.getId());
        if (null == position) {
            return ResponseResult.fail(ResponseCodeEnum.param_exception);
        }

        UserDiscountInfo userDiscountInfo = null;
        if (null != inDTO.getDiscountId()) {
            userDiscountInfo = userDiscountInfoService.getById(inDTO.getDiscountId());
            if (null == userDiscountInfo) {
                return ResponseResult.fail(ResponseCodeEnum.param_exception);
            }
        }


        BigDecimal serviceCharge = BigDecimal.valueOf(50);
        String baseServiceCharge = redisTemplate.opsForValue()
                .get(CacheKeyEnum.service_charge.getKey());
        if (StringUtils.isNotEmpty(baseServiceCharge)) {
            serviceCharge = new BigDecimal(baseServiceCharge);
        }
        try {
            BossOrder bossOrder = inDTO.buildOrder(baseUser, position, userDiscountInfo,serviceCharge);
            PayResult payResult = payFactory.pay(bossOrder);
            return ResponseResult.success(payResult);
        } catch (Exception e) {
            logger.error("下单出现异常",e);
            return ResponseResult.fail(ResponseCodeEnum.server_exception);
        }
    }


    @ApiOperation(value = "申请退款")
    @PostMapping("/refund")
    public ResponseResult<String> refund(@RequestBody @Validated IdInDTO inDTO) {
        BossOrder bossOrder = orderService.getById(inDTO.getId());
        if (null == bossOrder) {
            return ResponseResult.fail();
        }

        BossPosition position = bossPositionService.getById(bossOrder.getExtId());
        if (position.getStatus() == 2) {
            return ResponseResult.fail(ResponseCodeEnum.position_vacant_cant_refund);
        }
        orderService.updateStatus(inDTO.getId(), 3);
        return ResponseResult.success();
    }


    @ApiOperation(value = "申请发票", notes = "id为订单id")
    @PostMapping("/apply/invoice")
    public ResponseResult<String> applyInvoice(@RequestBody @Validated IdInDTO inDTO) {
        BossOrder bossOrder = orderService.getById(inDTO.getId());
        if (null == bossOrder) {
            return ResponseResult.fail();
        }

        if (bossOrder.getStatus() == 3) {
            return ResponseResult.fail(ResponseCodeEnum.all_refund_cant_invoice);
        }

        BossPosition position = bossPositionService.getById(bossOrder.getExtId());
        if (position.getStatus() == 2) {
            return ResponseResult.fail(ResponseCodeEnum.position_vacant_cant_invoice);
        }

        orderService.updateInvoiceStatus(inDTO.getId(), 2);
        return ResponseResult.success();
    }

    @ApiOperation(value = "删除记录")
    @PostMapping("/delete")
    public ResponseResult<String> delete(@RequestBody @Validated IdInDTO inDTO) {
        orderService.logicDelete(inDTO.getId());
        return ResponseResult.success();
    }


}
